package com.lcj.bff.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.lcj.bff.customer.controller.form.*;
import com.lcj.bff.customer.entity.VoucherEntity;
import com.lcj.bff.customer.feign.*;
import com.lcj.bff.customer.service.OrderService;
import com.lcj.common.entity.OrderStatusEnum;
import com.lcj.common.exception.AochException;
import com.lcj.common.util.PageUtils;
import com.lcj.common.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private DrServiceApi drServiceApi;

    @Resource
    private OdrServiceApi odrServiceApi;

    @Resource
    private MpsServiceApi mpsServiceApi;

    @Resource
    private RuleServiceApi ruleServiceApi;

    @Resource
    private SnmServiceApi snmServiceApi;

    @Resource
    private VhrServiceApi vhrServiceApi;

    @Override
    public HashMap searchOrderById(SearchOrderForm form) {
        //查询订单信息
        Result r = odrServiceApi.searchOrderById(form);
        HashMap map = (HashMap) r.get("result");
        Long driverId = MapUtil.getLong(map, "driverId");
        if(driverId != null){
            DriverIdForm infoForm = new DriverIdForm();
            infoForm.setDriverId(driverId);
            //基本信息
            r = drServiceApi.searchDriverBriefInfo(infoForm);
            HashMap temp = (HashMap) r.get("result");
            map.putAll(temp);
            int status = MapUtil.getInt(map, "status");

            //status是6:未付款状态，额外查询最佳代金券
            if (status == OrderStatusEnum.UNPAID.getCode().intValue()) {
                SearchBestUnUseVoucherForm voucherForm = new SearchBestUnUseVoucherForm();
                voucherForm.setCustomerId(form.getCustomerId());
                BigDecimal total = new BigDecimal(MapUtil.getStr(map, "total"));
                voucherForm.setAmount(total);
                r = vhrServiceApi.searchBestUnUseVoucher(voucherForm);
                List<VoucherEntity> voucherList = (List<VoucherEntity>) r.get("result");
                map.put("voucher", voucherList);
            }

            //订单已完成，查询评价
            HashMap cmtMap = new HashMap();
            if (status >= 7) {
                r = odrServiceApi.searchCommentByOrderId(form);
                if (r.containsKey("result")) {
                    cmtMap = (HashMap) r.get("result");
                } else {
                    //无评价默认好评
                    cmtMap.put("rate", 5);
                }
            }
            map.put("comment", cmtMap);
            return map;
        }
        return null;
    }

    @Override
    @Transactional
    @LcnTransaction
    public Map createNewOrder(CreateNewOrderForm form) {
        Long customerId = form.getCustomerId();
        String startPlace = form.getStartPlace();
        String startPlaceLatitude = form.getStartPlaceLatitude();
        String startPlaceLongitude = form.getStartPlaceLongitude();
        String endPlace = form.getEndPlace();
        String endPlaceLatitude = form.getEndPlaceLatitude();
        String endPlaceLongitude = form.getEndPlaceLongitude();
        String favourFee = form.getFavourFee();
        /**
         * 【重新预估里程和时间】
         * 虽然下单前，系统会预估里程和时长，但是有可能顾客在下单页面停留时间过长，
         * 然后再按下单键，这时候路线和时长可能都有变化，所以需要重新预估里程和时间
         */
        EstimateOrderMileageAndMinuteForm form_1 = new EstimateOrderMileageAndMinuteForm();
        form_1.setMode("driving");
        form_1.setStartPlaceLatitude(startPlaceLatitude);
        form_1.setStartPlaceLongitude(startPlaceLongitude);
        form_1.setEndPlaceLatitude(endPlaceLatitude);
        form_1.setEndPlaceLongitude(endPlaceLongitude);
        Result r = mpsServiceApi.estimateOrderMileageAndMinute(form_1);
        HashMap map = (HashMap) r.get("result");
        String mileage = MapUtil.getStr(map, "mileage");
        int minute = MapUtil.getInt(map, "minute");

        /**
         * 重新估算订单金额
         */
        EstimateOrderChargeForm form_2 = new EstimateOrderChargeForm();
        form_2.setMileage(mileage);
        form_2.setTime(new DateTime().toTimeStr());
        r = ruleServiceApi.estimateOrderCharge(form_2);
        map = (HashMap) r.get("result");
        String expectsFee = MapUtil.getStr(map, "amount");
        String chargeRuleId = MapUtil.getStr(map, "chargeRuleId");
        short baseMileage = MapUtil.getShort(map, "baseMileage");
        String baseMileagePrice = MapUtil.getStr(map, "baseMileagePrice");
        String exceedMileagePrice = MapUtil.getStr(map, "exceedMileagePrice");
        short baseMinute = MapUtil.getShort(map, "baseMinute");
        String exceedMinutePrice = MapUtil.getStr(map, "exceedMinutePrice");
        short baseReturnMileage = MapUtil.getShort(map, "baseReturnMileage");
        String exceedReturnPrice = MapUtil.getStr(map, "exceedReturnPrice");

        //搜索适合接单的司机
        SearchBefittingDriverAboutOrderForm form_3 = new SearchBefittingDriverAboutOrderForm();
        form_3.setStartPlaceLatitude(startPlaceLatitude);
        form_3.setStartPlaceLongitude(startPlaceLongitude);
        form_3.setEndPlaceLatitude(endPlaceLatitude);
        form_3.setEndPlaceLongitude(endPlaceLongitude);
        form_3.setMileage(mileage);
        r = mpsServiceApi.searchBefittingDriverAboutOrder(form_3);
        ArrayList<HashMap> list = (ArrayList<HashMap>) r.get("result");

        //生成订单记录
        InsertOrderForm form_4 = new InsertOrderForm();
        form_4.setUuid(IdUtil.simpleUUID());
        form_4.setCustomerId(customerId);
        form_4.setStartPlace(startPlace);
        form_4.setStartPlaceLatitude(startPlaceLatitude);
        form_4.setStartPlaceLongitude(startPlaceLongitude);
        form_4.setEndPlace(endPlace);
        form_4.setEndPlaceLatitude(endPlaceLatitude);
        form_4.setEndPlaceLongitude(endPlaceLongitude);
        form_4.setExpectsMileage(mileage);
        form_4.setExpectsFee(expectsFee);
        form_4.setFavourFee(favourFee);
        form_4.setDate(new DateTime().toDateStr());
        form_4.setChargeRuleId(Long.parseLong(chargeRuleId));
        form_4.setCarPlate(form.getCarPlate());
        form_4.setCarType(form.getCarType());
        form_4.setBaseMileage(baseMileage);
        form_4.setBaseMileagePrice(baseMileagePrice);
        form_4.setExceedMileagePrice(exceedMileagePrice);
        form_4.setBaseMinute(baseMinute);
        form_4.setExceedMinutePrice(exceedMinutePrice);
        form_4.setBaseReturnMileage(baseReturnMileage);
        form_4.setExceedReturnPrice(exceedReturnPrice);
        //存储订单数据
        r = odrServiceApi.insertOrder(form_4);
        String orderId = MapUtil.getStr(r, "result");

        /*
         * 发送新订单通知给相关司机消息队列
         */
        if(list.size() > 0) {
            SendNewOrderMessageForm form_5 = new SendNewOrderMessageForm();
            String[] driverContent = new String[list.size()];
            for (int i = 0; i < list.size(); i++) {
                HashMap one = list.get(i);
                String driverId = MapUtil.getStr(one, "driverId");
                String distance = MapUtil.getStr(one, "distance");
                distance = new BigDecimal(distance).setScale(1, RoundingMode.CEILING).toString();
                driverContent[i] = driverId + "#" + distance;
            }
            form_5.setDriversContent(driverContent);
            form_5.setOrderId(Long.parseLong(orderId));
            form_5.setFrom(startPlace);
            form_5.setTo(endPlace);
            form_5.setExpectsFee(expectsFee);
            //里程转化成保留小数点后一位
            mileage = new BigDecimal(mileage).setScale(1, RoundingMode.CEILING).toString();
            form_5.setMileage(mileage);
            form_5.setMinute(minute);
            form_5.setFavourFee(favourFee);
            snmServiceApi.sendNewOrderMessageAsync(form_5); //异步发送消息
        }

        Map result=new HashMap();
        result.put("orderId",orderId);
        result.put("count",list.size());

        return result;

    }

    @Override
    public Integer searchOrderStatus(SearchOrderForm form) {
        Result r = odrServiceApi.searchOrderStatus(form);
        Integer status = MapUtil.getInt(r, "result");
        return status;
    }

    @Override
    @Transactional
    @LcnTransaction
    public String deleteUnAcceptOrder(SearchOrderForm form) {
        Result r = odrServiceApi.deleteUnAcceptOrder(form);
        String result = MapUtil.getStr(r, "result");
        return result;
    }

    @Override
    public HashMap hasCustomerCurrentOrder(CustomerIdForm form) {
        Result r = odrServiceApi.hasCustomerCurrentOrder(form);
        HashMap map = (HashMap) r.get("result");
        return map;
    }

    @Override
    public HashMap searchOrderForMoveById(SearchOrderForm form) {
        Result r = odrServiceApi.searchOrderForMoveById(form);
        HashMap map = (HashMap) r.get("result");
        return map;
    }

    @Override
    public boolean confirmArriveStartPlace(SearchOrderForm form) {
        Result r = odrServiceApi.confirmArriveStartPlace(form);
        boolean result = MapUtil.getBool(r, "result");
        return result;
    }

    @Override
    @Transactional
    @LcnTransaction
    public HashMap createWxPayment(long orderId, long customerId, Long customerVoucherId, Long voucherId) {
        /*
         * 1.先查询订单是否为未支付状态，其他状态都不可以生成支付订单
         */
        ValidCanPayOrderForm form_1 = new ValidCanPayOrderForm();
        form_1.setOrderId(orderId);
        form_1.setCustomerId(customerId);
        Result r = odrServiceApi.validCanPayOrder(form_1);
        HashMap map = (HashMap) r.get("result");
        String amount = MapUtil.getStr(map, "realFee");
        String uuid = MapUtil.getStr(map, "uuid");
        long driverId = MapUtil.getLong(map, "driverId");
        String discount = "0.00";
        //代金券抵扣
        if (customerVoucherId != null && voucherId != null) {
            UseVoucherForm form_2 = new UseVoucherForm();
            form_2.setCustomerId(customerId);
            form_2.setId(customerVoucherId);
            form_2.setVoucherId(voucherId);
            form_2.setOrderId(orderId);
            form_2.setAmount(amount);
            r = vhrServiceApi.useVoucher(form_2);
            discount = MapUtil.getStr(r, "result");
        }

        if (new BigDecimal(amount).compareTo(new BigDecimal(discount)) == -1) {
            throw new AochException("总金额不能小于优惠劵面额");
        }
        /*
         * 3.修改实付金额
         */
        amount = NumberUtil.sub(amount, discount).toString();
        UpdateBillPaymentForm form_3 = new UpdateBillPaymentForm();
        form_3.setOrderId(orderId);
        form_3.setRealPay(amount);
        form_3.setVoucherFee(discount);
        odrServiceApi.updateBillPayment(form_3);

        /*
         * 4.查询用户的OpenID字符串(用于创建微信支付订单)

        SearchOrderForm orderForm = new SearchOrderForm();
        orderForm.setCustomerId(customerId);
        orderForm.setDriverId(driverId);
        r = odrServiceApi.searchOpenId(orderForm);
        String customerOpenId = MapUtil.getStr(r, "customerOpenId");
        String driverOpenId = MapUtil.getStr(r, "driverOpenId");

        /*
         * 5.创建支付订单,微信支付无法调用......只能自己模拟了

        String prepayId = UUID.randomUUID().toString();
        //更新订单记录中的prepay_id(用于创建微信支付订单)
        UpdateOrderPrepayIdForm prepayIdForm = new UpdateOrderPrepayIdForm();
        prepayIdForm.setPrepayId(prepayId);
        prepayIdForm.setOrderId(orderId);
        odrServiceApi.updateOrderPrepayId(prepayIdForm);
         */
        map.clear();

        /*
        //(用于创建微信支付订单)
        map.put("nonceStr", "nonceStr");
        map.put("package", "prepay_id=" + prepayId);
        map.put("signType", "MD5");
        map.put("paySign", "paySign");
         */
        String timeStamp = new Date().getTime() + "";
        map.put("timeStamp", timeStamp);
        map.put("realPay", amount);
        map.put("uuid", uuid);

        return map;
    }

    @Override
    public PageUtils searchCustomerOrderByPage(SearchCustomerOrderByPageForm form) {
        Result r = odrServiceApi.searchCustomerOrderByPage(form);
        HashMap map = (HashMap) r.get("result");
        PageUtils pageUtils = BeanUtil.toBean(map, PageUtils.class);
        return pageUtils;
    }
}
